package ex 
{
	import flash.display.Bitmap;
	import flash.display.Graphics;
	import flash.display.GradientType;
	import flash.display.SpreadMethod;
	import flash.geom.Rectangle;
	import flash.geom.Point;
	import flash.geom.Matrix;
	import flash.net.*;
	import flash.text.StaticText;
	import flash.utils.ByteArray;
	import flash.display.*;
	import flash.filters.ShaderFilter;
	import ex.Circle;
	import ex.Rectangle;
	//import emb.ETiler;
	/**
	 * ...
	 * @author ...
	 */
	
	public class Map 
	{
		//Colliding group 
	//	private const VISIBLE_WIDTH:int = 14;
	//	private const VISIBLE_HEIGHT:int = 11;
		// 4 shaders
		[Embed(source="../../src/shaders/bilinear.pbj", mimeType="application/octet-stream")]
		private var _someFilter:Class;
		private var shader:Shader;
		private var shaderloader:URLLoader;
		private var bitmaploader:Loader;
		public var levelnum:int;
		
		private var tiler:ITiler;
		private var bitmap:BitmapData;
	//	private var s:Sprite;
		public var map:Array;
		public var omap:Array;
		
		[Embed(source = "../../assets/map1.png")]
		[Bindable]
		public var level1:Class;
		[Embed(source = "../../assets/o-map1.png")]
		[Bindable]
		public var olevel1:Class;
		[Embed(source = "../../assets/map2.png")]
		[Bindable]
		public var level2:Class;
		[Embed(source = "../../assets/o-map2.png")]
		[Bindable]
		public var olevel2:Class;
		[Embed(source = "../../assets/map3.png")]
		[Bindable]
		public var level3:Class;
		[Embed(source = "../../assets/o-map3.png")]
		[Bindable]
		public var olevel3:Class;
		//public var bm: Bitmap;
		//public var ob: Bitmap;
		public var dim: Point;
		public function Map(it:ITiler) 
		{
			//Dynamic tiler from xml
			/*
			if (!it)
				tiler = new ETiler;
			else
			*/
			tiler = it;
			dim = new Point(64, 64);
			map = new Array();
			omap = new Array();
			map[0] = (new level1() as Bitmap).bitmapData;
			omap[0] = (new olevel1() as Bitmap).bitmapData;
			map[1] = (new level2() as Bitmap).bitmapData;
			omap[1] = (new olevel2() as Bitmap).bitmapData;
			map[2] = (new level3() as Bitmap).bitmapData;
			omap[2] = (new olevel3() as Bitmap).bitmapData;
			levelnum = 0;
		}
		
		//Maps x,y to single unique z
		public function Cantor(x:int, y:int)
		{
			return (x + y) * (x + y + 1) / 2 + y;
		}
		
		public function drawon(g:Graphics)
		{
			shaderLoader();
			var matr:Matrix = new Matrix();
			map[levelnum] = tiler.getMap(levelnum);
			omap[levelnum] = tiler.getOMap(levelnum);
			bitmap = tiler.getTile(map[levelnum].getPixel(0,0)).clone();
			for (var i:int = 0; i < map[levelnum].height; i++)
			for (var j:int = 0; j < map[levelnum].width; j++)
			{
				
				//if (!(bm.bitmapData.getPixel(j, i) & 0x1000000)) 
				{	
					shader.data.topLeftImage.input = tiler.getTile(map[levelnum].getPixel(j, i),Cantor(j,i));
					if (i + 1 >= map[levelnum].height)
					{
						shader.data.bottomLeftImage.input = tiler.getTile(map[levelnum].getPixel(j, i),Cantor(j,i));
					}
					else 
					{
						shader.data.bottomLeftImage.input = tiler.getTile(map[levelnum].getPixel(j, i+1),Cantor(j,i+1));
					}
					if (j + 1 >= map[levelnum].width)
					{
						shader.data.topRightImage.input = tiler.getTile(map[levelnum].getPixel(j, i),Cantor(j,i));
					}
					else
					{
						shader.data.topRightImage.input = tiler.getTile(map[levelnum].getPixel(j+1, i),Cantor(j+1,i));
					}
					if ((i + 1 >= map[levelnum].height) && (j + 1 >= map[levelnum].width))
					{
						shader.data.bottomRightImage.input = tiler.getTile(map[levelnum].getPixel(j, i),Cantor(j,i));
					}
					else
					{
						shader.data.bottomRightImage.input = tiler.getTile(map[levelnum].getPixel(j + 1, i + 1), Cantor(j + 1, i + 1));
					}
					var shaderFilter:ShaderFilter = new ShaderFilter(shader);
					
					if (shader.data.bottomRightImage.input === shader.data.topRightImage.input &&
					shader.data.topRightImage.input === shader.data.bottomLeftImage.input &&
					shader.data.bottomLeftImage.input === shader.data.topLeftImage.input)
					{
						//g.addChild(shader.data.bottomLeftImage.input);
						//No filter needed - no mixing applies
						g.beginBitmapFill(shader.data.bottomLeftImage.input, matr, true, false);
						g.drawRect((j+0.5) * dim.x, (i+0.5) * dim.y, dim.x, dim.y);
					}
					else
					{
				    bitmap = shader.data.topLeftImage.input.clone();
					bitmap.applyFilter(shader.data.topLeftImage.input, bitmap.rect, bitmap.rect.topLeft, shaderFilter);
					matr.identity();
					matr.translate((j+0.5) * dim.x, (i+0.5) * dim.y);
					//g.beginBitmapFill(shader.data.topLeftImage.input, matr, true, true);
					g.beginBitmapFill(bitmap, matr, false, false);
					g.drawRect((j + 0.5) * dim.x, (i + 0.5) * dim.y, dim.x, dim.y);
					}
					//bm.bitmapData.setPixel(j, i, bm.bitmapData.getPixel(j, i) | 0x1000000);//Mark as drawn
					
				}

/*				var fillType:String = GradientType.RADIAL;
				var colors:Array = [0xFFFF00, 0x000000];
				var alphas:Array = [1, 1];
				var ratios:Array = [0x00, 0xFF];
		   
				matr.createGradientBox(dim.x, dim.y, 0, 0, 0);
				matr.translate(j * dim.x, i * dim.y);
				var spreadMethod:String = SpreadMethod.PAD;
				g.beginGradientFill(fillType, colors, alphas, ratios, matr, spreadMethod);		
				g.drawRect(0 + j*dim.x,0 + i*dim.y,dim.x,dim.y);*/
			}
			
			for (var i:int = 0; i < omap[levelnum].height; i++)
			for (var j:int = 0; j < omap[levelnum].width; j++)
			{
				if (!omap[levelnum].getPixel(j, i))
				{
					g.beginFill(0xCC5500);//temporary
					g.drawRect(j * dim.x, i * dim.y, dim.x, dim.y);
				}
				if (omap[levelnum].getPixel(j, i) == 0xFF)
				{
					//matr.identity();
					//matr.translate(j * dim.x, i * dim.y);
					g.beginFill(0x0000FF);//temporary
					//g.beginBitmapFill(bdt,matr,true);
					g.drawRect(j * dim.x, i * dim.y, dim.x, dim.y);
				}
				
			}
		}

		public function intersectsCircle (circle:Circle) : Boolean
		{
			return collidesCircle(circle, MovingCircle.GroupWall | MovingCircle.GroupWall2);
		}
		
		public function collidesCircle(circle:Circle, m:int):Boolean
		{
			var cr:flash.geom.Rectangle = circle.bounds();
			var ib: int = Math.floor(cr.left / dim.x);
			var ie: int = Math.floor(cr.right / dim.x);
			var jb: int = Math.floor(cr.top / dim.y);
			var je: int = Math.floor(cr.bottom / dim.y);
			for (var j:int = jb; j <= je;j++)
			for (var i:int  = ib; i <= ie; i++)
			{
				if (omap[levelnum].getPixel(i, j) == 0x0000FF)
				{
					if (!(m & MovingCircle.GroupWall2)) continue;
				}
				else
				if (omap[levelnum].getPixel(i, j) == 0)
				{
					if (!(m & MovingCircle.GroupWall)) continue;
				}
				else continue;
				//if (omap[levelnum].bitmapData.getPixel(i, j)  > 0) continue;
				//it's black, so we should check for collision
				if (new ex.Rectangle(i * dim.x, j * dim.y, dim.x, dim.y).intersectsCircle(circle))
				return true;
				
			}
			return false;
		}
		

		
		public function shaderLoader():void
		{
			
			shader= new Shader(new _someFilter() as ByteArray);

			//Shader params doesn't work
			/*
			shader.data.imageWidth = 32;
			shader.data.imageHeight = 32;
			*/
		//	onLoadComplete();
		//	s = new Sprite();
		//	s.graphics.beginShaderFill(shader);
		//	s.graphics.bi
	//		var bitmap = DisplayConverter.spriteToBitmap(s);
	//		bitmap = new Bitmap(bmp1.bitmapData.clone());
	//		bitmap.filters = [shaderFilter];
		//	var bitmap:Bitmap = bmp1;
		//	bmp1.filters = [shaderFilter];
/*			shaderloader = new URLLoader();
			shaderloader.dataFormat = URLLoaderDataFormat.BINARY;
			shaderloader.addEventListener(Event.COMPLETE, onLoadComplete);
			shaderloader.load(new URLRequest("/../shaders/bilinear.pbj"));
			trace(new URLRequest("file:C:/Documents and Settings/Gumbo/tank-survival/src/shaders/bilinear.pbj").data);
			trace(new URLRequest("bilinear.pbj").data);
			bitmaploader = new Loader();
			bitmaploader.load(new URLRequest("/../../assets/MARBLE.PNG"));
			trace(new URLRequest("/../../assets/MARBLE.PNG").data);
			bmp1 = Bitmap(bitmaploader.content);
			trace(bmp1);
			bitmaploader.load(new URLRequest("/../../assets/PATCH.PNG"));
			bmp2 = Bitmap(bitmaploader.content);
			bitmaploader.load(new URLRequest("/../../assets/ROCKS.PNG"));
			bmp3 = Bitmap(bitmaploader.content);
			bitmaploader.load(new URLRequest("/../../assets/YELLOW.PNG"));
			bmp4 = Bitmap(bitmaploader.content);*/
		}
		public function onLoadComplete(/*event:Event*/):void
		{
//			shader = new Shader();
//			shader.byteCode = shaderloader.data;
			var s:Sprite = new Sprite();
			s.graphics.beginShaderFill(shader);
		//	var shaderFilter:ShaderFilter = new ShaderFilter(shader);
		//	bitmap= new Bitmap(bitmaploader.content);
		//	bitmap.filters = [shaderFilter];
		}
		
	}

}